package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * java反射机制
 * 反射是java的动态机制,它将原来写程序时进行的实例化操作以及操作属性,调用
 * 方法从编码期间确定转移到在程序运行期间确定.这大大的提高了代码的灵活度.
 * 但是反射带来了更多的系统开销和较慢的运行效率,因此仅在必要地方使用而不是
 * 过度的依赖反射.
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            使用反射机制操作一个类时,第一步就是获取该类的类对象
            Class的实例.
            JVM中每个被加载的类都有且只有一个Class的实例与之对应,
            这个Class的实例称为这个类的"类对象".通过类对象我们可以
            在程序运行期间获取到该类的一切信息(类名,有哪些方法,属性
            构造器等等)从而进行对应的操作.
            获取一个类的类对象有三种方式:
            1:类名.class
              例如:
              Class cls = String.class;
              Class cls = int.class;
              这种方式比较直接,但是缺点是硬编码获取一个类的类对象,不
              灵活.注:基本类型获取类对象的方式只有这一种

            2:Class.forName(String className)
              例如:
              Class cls = Class.forName("java.lang.String");

            3:类加载器ClassLoader
         */

        //获取String的类对象
//        Class cls = String.class;

//        Class cls = Class.forName("java.lang.String");
        /*
            java.lang.String,
            java.util.ArrayList
            java.io.FileInputStream,
            reflect.Person
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名:");
        String name = scanner.nextLine();
        Class cls = Class.forName(name);
        //获取该类的万全限定名(包名.类名)
        String className = cls.getName();
        System.out.println("类名:"+className);
        //仅获取类名
        className = cls.getSimpleName();
        System.out.println("类名:"+className);
        /*
            通过类对象获取该类所有的公开方法
         */
        Method[] methods = cls.getMethods();
        System.out.println(className+"类有"+methods.length+"个公开方法");
        for(Method m : methods){
            System.out.println(m.getName());
        }
    }
}
